package com.ysu.zyw.fk.security;

import com.ysu.zyw.common.constant.SystemConst;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;

import java.io.Serializable;
import java.util.Collection;
import java.util.Set;

/**
 * ShiroCacheManager is a shiro abstract of cache, in this we directly inject an spring
 * cache impl into an shiro impl, so all impl is based on spring abstract.
 * <p>
 * Created by ZeRur on 2016/1/17.
 *
 * @author yaowu.zhang
 */
public class ShiroCacheManager implements CacheManager {

    private Cache<String, ? extends Serializable> activeSessionCache;

    private Cache<String, ? extends Serializable> authenticationCache;

    private Cache<String, ? extends Serializable> authorizationCache;

    @SuppressWarnings("unchecked")
    public <K, V> Cache<K, V> getCache(String name) throws CacheException {
        switch (name) {
            case SystemConst.CacheNames.ACTIVE_SESSIONS_CACHE_NAME:
                return (Cache<K, V>) activeSessionCache;
            case SystemConst.CacheNames.AUTHENTICATION_CACHE_NAME:
                return (Cache<K, V>) authenticationCache;
            case SystemConst.CacheNames.AUTHORIZATION_CACHE_NAME:
                return (Cache<K, V>) authorizationCache;
            default:
                return null;
        }
    }

    public static class ShiroCache implements Cache<String, Serializable> {

        private org.springframework.cache.Cache cacheToUse;

        public ShiroCache(org.springframework.cache.Cache cacheToUse) {
            this.cacheToUse = cacheToUse;
        }

        public Serializable get(String key) throws CacheException {
            return cacheToUse.get(key, Serializable.class);
        }

        public Serializable put(String key, Serializable value) throws CacheException {
            cacheToUse.put(key, value);
            return value;
        }

        public Serializable remove(String key) throws CacheException {
            Serializable value = cacheToUse.get(key, Serializable.class);
            cacheToUse.evict(key);
            return value;
        }

        public void clear() throws CacheException {
            cacheToUse.clear();
        }

        public int size() {
            // TODO
            return 0;
        }

        public Set<String> keys() {
            // TODO
            return null;
        }

        public Collection<Serializable> values() {
            // TODO
            return null;
        }

        public org.springframework.cache.Cache getCacheToUse() {
            return cacheToUse;
        }

        public void setCacheToUse(org.springframework.cache.Cache cacheToUse) {
            this.cacheToUse = cacheToUse;
        }

    }

    public Cache<String, ? extends Serializable> getActiveSessionCache() {
        return activeSessionCache;
    }

    public void setActiveSessionCache(Cache<String, ? extends Serializable> activeSessionCache) {
        this.activeSessionCache = activeSessionCache;
    }

    public Cache<String, ? extends Serializable> getAuthenticationCache() {
        return authenticationCache;
    }

    public void setAuthenticationCache(Cache<String, ? extends Serializable> authenticationCache) {
        this.authenticationCache = authenticationCache;
    }

    public Cache<String, ? extends Serializable> getAuthorizationCache() {
        return authorizationCache;
    }

    public void setAuthorizationCache(Cache<String, ? extends Serializable> authorizationCache) {
        this.authorizationCache = authorizationCache;
    }

}
